<template>
  <div>
    <Modal
      v-show="!isWindowed"
      :title="title"
      v-model="isShow"
      width="800"
      :closable="false"
      :mask-closable="false"
      class="automation-step"
    >
      <template v-if="isPre">
        <template v-if="type === 5">
          <Alert type="warning" show-icon>
            <!-- 新护网 hwType0 护网演练 2  众测演练 3 日常渗透-->
            <template v-if="hwType === 1||hwType === 3">
              <p>1.请先选定裁判才能导入目标进入后续步骤。</p>
              <!-- <p>
                2.
                若选定裁判为空，报告持续提交任务不会自动绑定裁判，后续可至“报告持续提交”页面手动设置绑定
              </p> -->
            </template>
            <!-- 其他 -->
            <template v-else>
              
              <p v-if="hwType!=2 && pageRouter.indexOf('swDrill')>-1">
                <!--             21629   仿真，众测，实网 ，都没有，只有护网有-->
                1. 导入目标之前，请先去“拓扑页 > 展示编辑 > 3D编辑 > 地理区域划分”中，进行“行政区”处理
              </p>
              <p>{{hwType!=2 && pageRouter.indexOf('swDrill')>-1?'2':'1'}}.请先选定裁判才能导入目标进入后续步骤</p>
              <!-- <p>
                3.若选定裁判为空，报告持续提交任务不会自动绑定裁判，后续可至“报告持续提交”页面手动设置绑定
              </p> -->
            </template>
          </Alert>
          <div class="referee">
            <label>裁判:</label>
            <Select filterable v-model="referee" filterable multiple clearable>
              <Option
                v-for="(item, index) in refereeList"
                :key="index"
                :value="item.id"
                :title="`${item.nickname}--${item.username}`"
                >{{ item.nickname + '--' + item.username }}</Option
              >
            </Select>
          </div>
          <div class="mr15" style="display: inline-block;" v-if="referee.length">
            <Upload
              ref="upload"
              :disabled="mixinUploadLoading"
              :action="mixinUploadAction"
              :show-upload-list="false"
              :on-format-error="mixinHandleFormatError"
              :on-success="uploadSuccess"
              :format="mixinFormat"
              :before-upload="mixinBeforeUpload"
              :headers="mixinUploadHeader"
              style="display:inline-block;"
            >
            <!-- :on-exceeded-size="mixinFileHasExceed" -->
              <Button
                type="primary"
                ghost
                icon="ios-cloud-upload-outline"
                :disabled="disabled"
                :loading="mixinUploadLoading"
                >导入目标</Button
              >
            </Upload>
            <WarningTip content="请上传xlsx格式文件"></WarningTip>
            <!-- ，文件大小不能超过10MB -->
          </div>
          <Button
            type="primary"
            ghost
            icon="ios-cloud-download-outline"
            :disabled="disabled"
            class="mr15"
          >
            <a :href="mixinTemplateUrl" download="" @click.stop>模板下载</a>
          </Button>
        </template>
        <template v-if="type === 2">
          <Input search enter-button="确定" v-model.trim="domain" :placeholder="domainTip" @on-blur="validateDomain" @on-search="startAutoConfig" :maxlength="20">
            <span slot="prepend">域名</span>
          </Input>
          <div class="form-item-error-tip" v-if="domainErrorTip">{{domainErrorTip}}</div>
        </template>
      </template>
      <template v-else>
        <Alert :type="stepsToComplete && !hasErrorStep ? 'success' : 'warning'" show-icon>
          {{
            stepsToComplete
              ? hasErrorStep
                ? '存在异常步骤，请切换至复杂模式，手动配置'
                : '自动配置完成'
              : `正在自动配置${drillTypeText}，请停留在当前页面直至配置完成......`
          }}
        </Alert>
        <Steps :current="0" direction="vertical">
          <template v-for="item in steps">
            <step
              :key="item.step"
              :content="stepNameList[item.step]"
              :status="statusList[item.status]"
            ></step>
            <Tooltip
              :content="item.errMsg"
              :key="`${item.step}-div`"
              v-if="item.errMsg"
              class="step-error"
              transfer
              placement="top-start"
            >
              <span style="color: #ed4014;"></span>
            </Tooltip>
          </template>
        </Steps>
      </template>
      <div slot="footer">
        <Button @click="confirmHide" type="primary" v-if="hwType !== 3">{{
          isPre ? '关闭' : stepsToComplete ? '关闭' : '窗口化'
        }}</Button>
        <Button v-else @click="confirmHide" type="primary" :loading="isSetting">{{isSetting?'配置中':'关闭'}}</Button>
      </div>
    </Modal>
    <div v-show="isWindowed" class="windowed" v-drag>
      <div class="header">
        <span class="title">{{ title }}</span>
        <Button icon="md-browsers" type="text" @click="isWindowed = false"></Button>
      </div>
      <div class="progress">
        <Progress :percent="percent" :stroke-width="20" text-inside :status="progressStatus" />
      </div>
    </div>
  </div>
</template>

<script>
import { getAutoStatus, autoConfig } from '@/api/drill_compete';
import { queryCompanyUsers } from '@/api/users.js';
import hwTargetMangeMixin from '@/mixin/hwTargetMangeMixin';
import dragMixin from '@/mixin/dragMixin';
import {validateDomain,domainTip} from '@/libs/reg'
export default {
  name:'automationStep',
  props: {
    type: {
      // 默认的渗透赛
      type: Number,
      default: 4
    },
    disabled: {
      type: Boolean,
      default: true
    },
    isOnline: {
      type: Boolean,
      default: false
    },
    isDistributed: {
      type: Number,
      default: 0
    },
    hwType:{
      type: Number,
      default: 0
    },
    path:{
      type:String,
      default:""
    }
  },
  mixins: [hwTargetMangeMixin, dragMixin],
  computed: {
    drill() {
      if(this.type == 5 && this.hwType == 2) {
        return {
          name: '众测演练',
          type: '演练'
        }
      }
      if(this.type == 5 && this.hwType == 4) {
        return {
          name: '仿真对抗',
          type: '对抗'
        }
      }
      if(this.type == 5 && this.hwType == 3) {
        return { name: '日常渗透', type: '演练'}
      }
      if(this.type == 5 && this.hwType == 0) {
        return { name: '护网演练', type: '演练'}
      }
      return this.drillType[String(this.type)] || {};
    },
    title() {
      if (this.drill.name&&this.path!='实网测试') {
        return `${this.drill.name}-自动配置${this.drill.type}`;
      }
      if(this.path=='实网测试'){
        return `实网测试-自动配置${this.drill.type}`;
      }
    },
    drillTypeText() {
      return this.drill.type ? this.drill.type : '';
    },
    stepsToComplete() {
      return this.steps.length && [0, 1].includes(this.steps[this.steps.length - 1].status);
    }
  },
  data() {
    return {
      pageRouter:this.$route.name, // swDrill护网的    'fzDrillDetail',zcDrillDetail
      domainTip,
      hasErrorStep: false,
      isStart: false,
      referee: [], // 裁判
      percent: 0, // 进度条百分比
      progressStatus: 'active',
      isWindowed: false, // 是否窗口化
      isPre: false,
      isShow: false,
      domain: '', // 域名
      domainErrorTip:'',
      sceneDetail: {},
      steps: [],
      refereeList: [], // 裁判列表
      drillType: {
        '1': {
          name: '攻防赛',
          type: '比赛'
        },
        '2': {
          name: '夺旗赛',
          type: '比赛'
        },
        '4': {
          name: '渗透演练',
          type: '演练'
        },
        '5': {
          name: '实网测试',
          type: '演练'
        },
        '8': {
          name: 'AWDP',
          type: '比赛'
        },
        '9': {
          name: '运维赛',
          type: '比赛'
        }
      },
      // step是从1开始计算的，所以数组首位特意设置为空
      stepNameList: [
        '',
        `${[4, 5].includes(this.type) ? '演练' : '竞赛'}题目配置`, // 1
        '接入机器分配', // 2
        '目标导入', // 3
        '显示题目', // 4
        '目标分配', // 5
        '题目分配', // 6
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'下发VPN出口路由':'下发基础规则'}`, // 7
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'下发团队出口路由':'下发端口转发规则'}`, // 8
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'下发竞赛路由':'下发公网路由规则'}`, // 9
        '域名生成', // 10 
        '下发团队路由规则',  // 11
        '下发竞赛系统路由规则', // 12
        '隐藏所有题目', // 13
        '流量过滤配置', // 14
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'下发VPN路由基础配置':'静态Flag配置'}`, // 15
        '动态Flag配置', // 16
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'生成VPN':'Flag服务器配置'}`, // 17
        `${this.type == 5 && (this.hwType == 2 || this.hwType == 4)?'分发VPN':'Flag持续提交'}`, // 18
        '报告持续提交', // 19
        '答题系统通道配置', // 20
        '选手自带答题设备接入申请', // 21
        `${this.type == 5 ? '流量镜像配置':'checker配置'}`, // 22
        // 'checker配置'
      ],
      statusList: ['error', 'finish', 'wait', 'process'], // 0:失败 1:成功 2:等待 3:进行中 4:无需操作
      isSetting: false, // 是否配置中
    };
  },
  watch: {
    disabled: {
      immediate: true,
      async handler(newValue) {
        if (!newValue) {
          if (this.type === 5) {
            // 护网演练需要先查出裁判列表用于选择
            await this.getrefereeList();
          }
          this.getAutoStep();
        }
      }
    },
    isWindowed(newValue) {
      this.$emit('on-window-state-change', newValue);
    },
    stepsToComplete(newValue) {
      if (newValue) {
        this.hasErrorStep = this.steps.some((item) => item.status === 0);
      }
    }
  },
  mounted() {
    if (this.type === 8) {
      // 攻防赛plus第八个步骤需要改名为 “开放靶标端口”
      this.stepNameList[8] = '开放靶标端口';
    }
  },
  methods: {
    // 获取裁判列表
    getrefereeList() {
      return new Promise((resolve) => {
        queryCompanyUsers({
          pageIndex: 1,
          pageSize: 2147483646,
          role: 'referee'
        })
          .then(({ code, message, data }) => {
            if (code == 1) {
              this.refereeList = data.items;
            } else {
              this.$Message.warning(message);
            }
          })
          .catch(() => {
            this.$Message.error('获取裁判列表异常');
          })
          .finally(() => {
            resolve();
          });
      });
    },
    // 获取配置进度
    getAutoStep() {
      clearTimeout(this.timer);
      getAutoStatus({
        sceneId: this.$route.query.id,
        pageIndex: 1,
        pageSize: 2147483646
      })
        .then(({ code, message, data = {} }) => {
          if (code !== 1) {
            this.$Message.warning(message);
          } else {
            let items = (data.items || []).filter((item) => item.status !== 4); // 过滤掉不需要操作的步骤
            if (items.length === 0) {
              // 没有步骤什么都不做
              return;
            }
            console.log(this.steps, 'this.stepsthis.steps');
            this.steps = items;
            if (this.isDistributed == 1 && this.type == 2) {
              this.steps.splice(5, 1);
            }
            // status 0:失败 1:成功 2:等待 3:进行中 4:无需操作
            if (items[0].status === 2) {
              // 第一步都没有开始的话，需要开始配置
              this.show();
              if ((this.type === 5 || (this.type === 2 && this.isOnline)) && !this.isStart) {
                // 还未开始配置，护网演练与线上夺旗赛有前提条件需要设置
                this.isPre = true;
              } else {
                this.autoConfig();
              }
            } else if ([2, 3].includes(items[items.length - 1].status)) {
              // 最后一步等待或者进行中
              if (this.isShow === false) {
                // 没打开模态框需要打开模态框
                this.show();
              }
              this.timer = setTimeout(() => {
                this.getAutoStep();
              }, 2000);
              let completeList = items.filter((item) => [0, 1].includes(item.status)) || [];
              this.percent = Math.floor((completeList.length / items.length) * 100);
            } else if ([0, 1].includes(items[items.length - 1].status)) {
              // 最后一步成功或者失败，清除定时器
              this.percent = 100;
              this.progressStatus = items.some((item) => item.status === 0) ? 'wrong' : 'active'; // 有失败的步骤，标记为告警
              this.$emit('finish');
              clearTimeout(this.timer);
              if(this.hwType == 3) {
                this.hide()
                this.isSetting = false
              }
            }
          }
        })
        .catch(() => {
          this.$Message.error('获取配置进度异常');
        });
    },
    // 文件上传后的回调
    uploadSuccess({ code, message }) {
      this.mixinUploadLoading = false;
      if (code !== 1) {
        this.$Message.warning(message);
      } else {
        this.startAutoConfig();
      }
    },
    validateDomain(){
      if(!(this.domain && this.domain.trim())){
        this.domainErrorTip = '域名不能为空';
        return
      }
      validateDomain('',this.domain,(data) => {
        this.domainErrorTip = data ? data.toString().split(':')[1] : '';
      })
    },
    // 开始自动配置
    startAutoConfig() {
      // if (this.type === 2 && this.isOnline && !(this.domain && this.domain.trim())) {
      //   this.$Message.warning('域名不能为空');
      //   return;
      // }
      if (this.type === 2 && this.isOnline){
        this.validateDomain();
        if(this.domainErrorTip){
          return
        }
      }
      if(this.hwType !== 3) {
        this.isPre = false
      }
      // this.isPre = false;
      this.autoConfig();
    },
    // 自动配置
    autoConfig() {
      this.isSetting = true
      if (!this.isStart) {
        // 还未开始，将第一步手动设置为进行中，同时将状态设置为开始
        this.$set(this.steps[0], 'status', 3);
        this.isStart = true;
      }
      this.timer = setTimeout(() => {
        this.getAutoStep();
      }, 2000);
      autoConfig(
        this.$route.query.id,
        this.type === 2 && this.isOnline ? this.domain : undefined,
        this.type === 5 ? this.referee : undefined
      )
        .then(({ code, message }) => {
          if (code !== 1) {
            // 自动配置失败，清除定时器，没必要在定时获取状态
            this.$Message.warning(message);
            clearTimeout(this.timer);
          }
        })
        .catch(() => {
          // 配置异常，同上
          this.$Message.error('自动配置异常');
          clearTimeout(this.timer);
        });
    },
    hide() {
      this.isShow = false;
    },
    show() {
      this.isShow = true;
    },
    // 确认是否关闭自动配置模态框
    confirmHide() {
      if (this.isPre) {
        this.$Modal.confirm({
          title: '确认退出自动配置吗',
          content: `${
            this.type === 2 ? '尚未设置域名' : '尚未导入目标'
          }，不会进行自动配置，若要重新配置，请重新进入本详情页`,
          onOk: () => {
            this.$emit('on-config-suspend', true);
            this.hide();
          }
        });
        return;
      }
      if (!this.stepsToComplete) {
        this.isWindowed = true;
        return;
      }
      this.hide();
    }
  },
  beforeDestroy() {
    clearTimeout(this.timer);
  }
};
</script>

<style scoped>
.referee {
  display: flex;
  margin: 20px 0;
  align-items: center;
}
.referee > label {
  width: 60px;
  text-align: center;
}
.windowed {
  width: 330px;
  height: 64px;
  position: fixed;
  bottom: 0;
  right: 0;
  padding: 4px 0;
  background-color: #ffffff;
  box-shadow: 0 0px 10px rgb(0 0 0 / 30%);
  z-index: 99999;
}
.windowed:hover {
  box-shadow: 0 0px 10px rgb(0 0 0 / 40%);
}
.windowed > .header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  padding: 0 10px;
  border-bottom: 1px solid #e7e7f1;
}
.windowed > .header > .title {
  font-size: 12px;
}
.windowed > .header /deep/ button {
  padding: 0;
}
.windowed > .header /deep/ button i {
  font-size: 16px;
}
.windowed > .progress {
  padding: 0 10px;
}
.mr15 {
  margin-right: 15px;
}
.automation-step {
  width: 100%;
}
.automation-step /deep/ .ivu-steps-status-process .ivu-steps-head-inner {
  border-color: #ffffff !important;
  background-color: #ffffff !important;
}
.automation-step /deep/ .ivu-steps-status-process .ivu-steps-head-inner span {
  color: #2d8cf0 !important;
}
.automation-step /deep/ .ivu-steps-status-process .ivu-steps-head-inner span::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px #2d8cf0 solid;
  clip: rect(0, 20px, 80px, 0);
  animation: loading 1.1s infinite linear;
}
@keyframes loading {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.step-error {
  width: 100%;
  height: 26px;
  position: absolute;
  margin-top: -46px;
  z-index: 999;
}

.step-error /deep/ .ivu-tooltip-rel {
  height: 26px;
}

.step-error /deep/ .ivu-tooltip-rel span {
  display: block;
  height: 26px;
}
.form-item-error-tip{
    line-height: 1;
    padding-top: 6px;
    color: var(--error-btn-border);
}
</style>
